use crate::rpc::pb::system::system_service_client::SystemServiceClient;
use std::collections::HashMap;
use tonic::transport::Channel;
use tonic::{Request, Response, Status};
use utils::rpc::{RpcClientManager, RpcConfig, RpcError};

// 导入所有需要的类型
use crate::rpc::pb::{
    auth::*, dept::*, menu::*, oauth::*, permission::*, post::*, role::*, user::*,
};

// 导入宏
use crate::impl_client_methods;

#[derive(Clone)]
pub struct SystemRpcClient {
    manager: RpcClientManager,
}

impl SystemRpcClient {
    /// 创建 System RPC 客户端
    pub fn new(manager: RpcClientManager) -> Self {
        Self { manager }
    }

    /// 创建默认配置的客户端
    pub fn with_default_config() -> Self {
        let config = RpcConfig::default();
        let manager = RpcClientManager::new(config);
        Self::new(manager)
    }

    /// 获取 System 服务客户端
    #[tracing::instrument(skip(self))]
    async fn get_system_client(&self) -> Result<SystemServiceClient<Channel>, RpcError> {
        let channel = self.manager.get_connection("system").await?;
        Ok(SystemServiceClient::new(channel))
    }

    /// 健康检查
    #[tracing::instrument(skip(self))]
    pub async fn health_check(&self) -> HashMap<String, bool> {
        self.manager.health_check().await
    }

    /// 通用的RPC调用方法，减少重复代码
    async fn call_rpc<F, Req, Resp, Fut>(
        &self,
        f: F,
        request: Req,
    ) -> Result<Response<Resp>, Status>
    where
        F: FnOnce(SystemServiceClient<Channel>, Request<Req>) -> Fut,
        Fut: std::future::Future<Output = Result<Response<Resp>, Status>>,
    {
        let client = self
            .get_system_client()
            .await
            .map_err(|e| Status::unavailable(e.to_string()))?;
        f(client, Request::new(request)).await
    }

    impl_client_methods!();
}
